home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 2009 Bui Viet Thanh (thanhbv@gmail.com).
- *
- * This file is part of clicknlearn.
- *
- * clicknlearn is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * clicknlearn is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with clicknlearn. If not, see <http://www.gnu.org/licenses/>.
- */
-
- Components.utils.import("resource://clicknlearn/cnldao.js");
- Components.utils.import("resource://clicknlearn/ext/Observers.js");
-
- //////////////////////////
- function Remind() {
- }
-
- Remind.prototype.remindCurrentWord = function(){
- var word = CNL.DICLOOKUP.currentWord.replace("'", "''");
- var remind = CNL.currentDoc.getElementById('remindbox').value.replace("'", "''");
- CNL.DICLOOKUP.currentWord.replace("'", "''");
- var r = {"id": word, "remind": remind, "originalUrl": content.location.href, "read": 0};
- CNL_DAO.create(r);
- Observers.notify("cnl_wordAddOrModify", word);
-
- this.highlightWord(CNL.DICLOOKUP.currentWord);
- CNL.DICLOOKUP.clearAll();
- }
-
- Remind.prototype.removeCurrentWord = function(){
- CNL_DAO.setWordRead(CNL.DICLOOKUP.currentWord);
- Observers.notify("cnl_wordAddOrModify", CNL.DICLOOKUP.currentWord);
- // this.unHighlightWord(CNL.DICLOOKUP.currentWord);
- CNL.DICLOOKUP.clearAll();
- }
-
- Remind.prototype.nodeDepth = function(node){
- var depth = 0;
- var body = window.content.document.body;
- while(node != body){
- depth++;
- node = node.parentNode;
- }
- return depth;
- }
- Remind.prototype.surround = function(range){
- //range.startContainer is always TextNode?
- var doc = window.content.document;
- var surroundNode = doc.createElement("span");
- surroundNode.setAttribute("class", "clicknlearnRemind");
- if(range.startContainer.parentNode == range.endContainer.parentNode){
- range.surroundContents(surroundNode);
- return;
- }
- //find commond parent node of the start point & end point
- var s = range.startContainer.parentNode;
- var sdepth = this.nodeDepth(s);
- var e = range.endContainer.parentNode;
- var edepth = this.nodeDepth(e);
- for(;sdepth > edepth; sdepth--)
- s = s.parentNode;
- for(;edepth > sdepth; edepth--)
- e = e.parentNode;
- while(s != e){
- s = s.parentNode;
- e = e.parentNode;
- }
- var p = s;//common parent
- //do surround
- s = range.startContainer;
- e = range.endContainer;
- var eOffset = range.endOffset;
- while(s.parentNode != p){
- range.setEnd(s.parentNode, s.parentNode.childNodes.length);
- range.surroundContents(surroundNode.cloneNode(true));
- range.setStartAfter(s.parentNode);
- s = s.parentNode;
- }
-
- s = range.startContainer;
- var sOffset = range.startOffset;
- range.setEnd(e, eOffset);
- while(e.parentNode != p){
- range.setStart(e.parentNode, 0);
- range.surroundContents(surroundNode.cloneNode(true));
- range.setEndBefore(e.parentNode);
- e = e.parentNode;
- }
-
- range.setStart(s, sOffset);
- range.surroundContents(surroundNode);
- }
-
- /**
- * See: nsIFind - http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/interfaces/nsIFind
- * Range - http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
- */
- Remind.prototype.highlightWords = function(){
- var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
- .QueryInterface(Components.interfaces.nsIFind);
-
- var doc = window.content.document;
- var body = doc.body;
-
- var count = body.childNodes.length;
- var mSearchRange = doc.createRange();
- var mStartPt = doc.createRange();
- var mEndPt = doc.createRange();
- mSearchRange.setStart(body, 0);
- mSearchRange.setEnd(body, count);
- mEndPt.setStart(body, count);
- mEndPt.setEnd(body, count);
-
- var statement = CNL_DAO.selectUnreadWordsStm();
- //if range represent 'in' in a word 'inova' then we should not highlight it
- var isRangeAWord, i;
- statement.executeAsync({
- handleResult: function(aResultSet) {
- for (var row = aResultSet.getNextRow(); row; row = aResultSet.getNextRow()) {
- var word = row.getResultByName("word");
- var rs = new Array();
-
- mStartPt.setStart(body, 0);
- mStartPt.setEnd(body, 0);
- var foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
- while(foundRange != null){
- //TODO haven't tested
- //check start of a word:
- // alert(word + ": start: " + foundRange.startContainer.nodeType + ", " + foundRange.startOffset +
- // ", end: " + foundRange.endContainer.nodeType + ", " + foundRange.endOffset);
- //TODO foundRange.startContainer & endContainer is always TEXT_NODE???
- if(foundRange.startContainer.nodeType != Node.TEXT_NODE)
- isRangeAWord = true;
- else{
- i = foundRange.startOffset;
- isRangeAWord = i == 0
- || ! CNLUtils.VALID_CHARS.test(foundRange.startContainer.textContent[i - 1]);
- }
- //check end of a word:
- //Only check if check start successfully
- if(isRangeAWord)
- if(foundRange.endContainer.nodeType == Node.TEXT_NODE){
- i = foundRange.endOffset;
- isRangeAWord = i == foundRange.endContainer.textContent.length
- || ! CNLUtils.VALID_CHARS.test(foundRange.endContainer.textContent[i]);
- }
- if(isRangeAWord)
- rs[rs.length] = foundRange;
- mStartPt.setStart(foundRange.endContainer, foundRange.endOffset);
- mStartPt.setEnd(foundRange.endContainer, foundRange.endOffset);
- foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
- }
-
- for(i=0; i<rs.length; i++)
- CNL.REMIND.surround(rs[i]);
- }
- },
- handleError: function(aError) {
- // print("Error: " + aError.message);
- },
- handleCompletion: function(aReason) {
- // if (aReason != Components.interfaces.mozIStorageStatementCallback.REASON_FINISHED)
- // print("Query canceled or aborted!");
- }
- });
- }
-
- Remind.prototype.highlightWord = function(word){
- var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance()
- .QueryInterface(Components.interfaces.nsIFind);
-
- var doc = window.content.document;
- var body = doc.body;
-
- var count = body.childNodes.length;
- var mSearchRange = doc.createRange();
- var mStartPt = doc.createRange();
- var mEndPt = doc.createRange();
- mSearchRange.setStart(body, 0);
- mSearchRange.setEnd(body, count);
- mEndPt.setStart(body, count);
- mEndPt.setEnd(body, count);
-
- //if range represent 'in' in a word 'inova' then we should not highlight it
- var isRangeAWord, i;
-
- var rs = new Array();
-
- mStartPt.setStart(body, 0);
- mStartPt.setEnd(body, 0);
- var foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
- while(foundRange != null){
- //TODO haven't tested
- //check start of a word:
- //TODO foundRange.startContainer & endContainer is always TEXT_NODE???
- if(foundRange.startContainer.nodeType != Node.TEXT_NODE)
- isRangeAWord = true;
- else{
- i = foundRange.startOffset;
- isRangeAWord = i == 0
- || ! CNLUtils.VALID_CHARS.test(foundRange.startContainer.textContent[i - 1]);
- }
- //check end of a word:
- //Only check if check start successfully
- if(isRangeAWord)
- if(foundRange.endContainer.nodeType == Node.TEXT_NODE){
- i = foundRange.endOffset;
- isRangeAWord = i == foundRange.endContainer.textContent.length
- || ! CNLUtils.VALID_CHARS.test(foundRange.endContainer.textContent[i]);
- }
- if(isRangeAWord)
- rs[rs.length] = foundRange;
- mStartPt.setStart(foundRange.endContainer, foundRange.endOffset);
- mStartPt.setEnd(foundRange.endContainer, foundRange.endOffset);
- foundRange = finder.Find(word, mSearchRange, mStartPt, mEndPt);
- }
-
- for(i=0; i<rs.length; i++)
- CNL.REMIND.surround(rs[i]);
- }
-